feat: SHOW/DESCRIBE/CREATE/DROP JSON STRUCTURE#80
Conversation
AI Code ReviewCritical IssuesMDL Syntax Design ViolationThe CUSTOM NAME MAP syntax uses Fix Required: Change syntax to use colon format: or multi-line: Missing VS Code Extension UpdateNew LSP capabilities were added (completions for JSON STRUCTURES, STRUCTURE, CUSTOM NAME MAP) but UTF-8 Bug in capitalizeFirstRuneThe func capitalizeFirstRune(s string) string {
if s == "" {
return s
}
runes := []rune(s)
runes[0] = rune(strings.ToUpper(string(runes[0]))[0]) // BUG:
---
*Automated review via OpenRouter (Nemotron Super 120B) — [workflow source](https://github.com/mendixlabs/mxcli/blob/main/.github/workflows/ai-review.yml)* |
AI Code ReviewOkay, I need to review this pull request against the checklist provided. Let me analyze the PR systematically. Overview of the PRThis PR adds full DDL support for JSON structures:
The PR includes changes to multiple files across the project, following the pattern of other similar features. Review Checklist AnalysisOverlap & duplication
MDL syntax designLet me check if the new MDL syntax follows the guidelines:
Automated review via OpenRouter (Nemotron Super 120B) — workflow source |
|
Issue 1: CUSTOM NAME MAP syntax: AS is the established MDL keyword for name mapping/aliasing. It's used consistently throughout the codebase: PUBLISH ENTITY ... AS 'name', MAP (Old AS New), SQL CONNECT ... AS alias, OldPlaceholder AS NewPlaceholder. The Key: value colon format is for properties, not name mappings. This is correct as-is. Issue 2: VS Code extension: No new LSP capabilities were added (just keyword completions, which are already handled by the Issue 3: UTF-8 bug: This is a valid finding. strings.ToUpper(string(runes[0]))[0] indexes a byte, not a rune. For multi-byte uppercase characters this would truncate. |
|
@peterjumpnl i think the review bot can also use some improvements. The as keyword is fine for mappings. I'll update the review bot. |
ako
left a comment
There was a problem hiding this comment.
Review
Well-structured PR — single feature, full pipeline coverage, good documentation. This is one of the better-scoped PRs in the series.
Full-stack checklist
| Step | Status |
|---|---|
| Grammar (lexer + parser) | ✅ STRUCTURES, CUSTOM_NAME_MAP tokens; createJsonStructureStatement, customNameMapping rules |
| Parser regenerated | ✅ |
| AST | ✅ CreateJsonStructureStmt, DropJsonStructureStmt |
| Visitor | ✅ visitor_jsonstructure.go |
| Executor | ✅ cmd_jsonstructures.go |
| BSON reader/writer | ✅ parser_misc.go, writer_jsonstructure.go |
| DESCRIBE roundtrip | ✅ Outputs re-executable CREATE OR REPLACE MDL |
| Catalog | ✅ json_structures table |
| Autocomplete | ✅ DESCRIBE/DROP completion |
| LSP keywords | ✅ lsp_completions_gen.go |
| Quick reference | ✅ |
| Skill docs | ✅ rest-client.md updated |
| Test examples | ✅ 20-json-structure-examples.mdl |
Issues
1. int32 for property values — contradicts PR #71 (needs verification)
The writer uses int32 for FractionDigits, MaxLength, MaxOccurs, MinOccurs, TotalDigits:
{Key: "FractionDigits", Value: int32(elem.FractionDigits)},
{Key: "MaxLength", Value: int32(elem.MaxLength)},PR #71 (just merged) established that property values must be int64 because Studio Pro's type cache matches by BSON wire type. The PR description says "Verified against Studio Pro" — if Studio Pro genuinely stores JsonStructures$JsonElement properties as int32, this is fine but should have a comment explaining why this type differs from the int64 convention. Otherwise, these should be int64 for consistency.
The parser also reads these as int32:
if v, ok := raw["MinOccurs"].(int32); ok {If Studio Pro actually writes int64 here, the parser will silently skip these fields (they'll keep the default -1 values).
2. Non-deterministic DESCRIBE output for custom name maps
for jsonKey, customName := range customMappings {Go map iteration order is random. If a structure has multiple custom name mappings, DESCRIBE will produce different output on each run. This breaks the "re-executable" guarantee and makes diffs noisy. Use a sorted key slice instead.
3. Unchecked errors in JSON parsing
In buildElementFromRawObject:
dec.Token() // opening { — error ignored
// ...
dec.Decode(&rawVal) — error ignoredIf the JSON is malformed partway through (already validated at the top level, but sub-objects aren't re-validated), these will silently produce incomplete element trees. At minimum, check the dec.Token() error.
4. Whitespace-only changes
reader_types.go and cmd_catalog.go contain alignment-only changes (reformatting struct tags and map literals). These add noise to the diff without functional change. Prefer keeping these in a separate commit or omitting them.
Minor observations
singularizeis intentionally naive ("Addresses" → "Addresse") to match Studio Pro behavior — good, and documentediso8601Patternregex handles common ISO 8601 variants; edge cases (week dates, ordinal dates) won't match, which is correct since Studio Pro doesn't recognize those eithernormalizeDateTimeValuepads fractional seconds to 7 digits (.NET-style) — good attention to detail- Reserved name handling (
Id→_id,Type→_type) matches Studio Pro — the comment says "Name" is also reserved butreservedExposedNamesonly hasIdandType - The 444-line design doc (
docs/plans/2026-04-01-show-describe-json-structures.md) is committed — same question as prior PRs: is this intended to be permanent documentation? CUSTOM_NAME_MAPlexer token usesWS+to match multi-word keywords with embedded whitespace — this works but is unusual for this grammar (most multi-word constructs use separate tokens). Not a problem, just noting the pattern.
Recommendation
Address the int32/int64 question (verify against Studio Pro BSON) and fix the map iteration order in DESCRIBE. The rest is solid.
ako
left a comment
There was a problem hiding this comment.
Pushed a fix commit addressing the review feedback:
- Deterministic DESCRIBE output: custom name map keys are now sorted alphabetically
- Error handling in JSON parser:
dec.Token()anddec.Decode()errors are checked inbuildElementFromRawObject - int32 documentation: added comment explaining that
JsonStructures$JsonElementuses int32 for numeric properties (verified against Studio Pro BSON), unlike the int64 convention for most other document types
The whitespace-only changes in reader_types.go and cmd_catalog.go are cosmetic and not worth a separate commit to revert.
Ready to merge.
AI Code ReviewReview SummaryThis PR adds full DDL support for JSON structures in MDL (SHOW/DESCRIBE/CREATE/DROP JSON STRUCTURE) with complete pipeline implementation. The feature follows established patterns from existing similar features (Image Collections, Business Events) and provides comprehensive functionality including custom name mapping, DESCRIBE roundtrip, and catalog integration. What Looks Good
Minor Issues
RecommendationApprove the PR. The implementation is thorough, follows established patterns, and provides the requested functionality. The minor documentation gaps should be addressed before merging but don't block approval as the core functionality is complete and correct. The feature enables AI agents to use idempotent CREATE OR REPLACE JSON STRUCTURE operations as intended. Automated review via OpenRouter (Nemotron Super 120B) — workflow source |
…REATE/DROP/SHOW/DESCRIBE JSON STRUCTURE statements for defining JSON structures - Add JSON STRUCTURE grammar rules with SNIPPET and CUSTOM NAME MAP - Add json_structures catalog table tracking element count and snippet - Add STRUCTURES and CUSTOM_NAME_MAP lexer tokens - Add ShowJsonStructures and DescribeJsonStructure to AST query types - Add buildJsonStructures() to catalog builder
…Upper. Replace strings.ToUpper roundtrip with direct unicode.ToUpper call for cleaner single-rune capitalization.
- Sort custom name map keys for deterministic DESCRIBE output - Check errors from json.Decoder.Token() and Decode() in snippet parser - Add comment explaining why JsonElement uses int32 (verified vs Studio Pro) Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
f2c3c2d to
3eb9406
Compare
AI Code ReviewCritical IssuesMissing ExportLevel ImplementationThe grammar defines
This violates the full-stack consistency requirement - the feature must be wired through the complete pipeline (grammar → AST → visitor → executor). While the plan document and grammar include Export Level support, the actual implementation omits this critical property. Moderate IssuesLSP Capabilities GapThe diff shows additions to VS Code Extension Update MissingThe checklist requires: "VS Code extension — if new LSP capabilities are added, update vscode-mdl/package.json" What Looks Good
RecommendationRequest changes to address the missing ExportLevel implementation across the AST/visitor/executor chain. This is a critical gap in the full-stack consistency required for MDL features. The LSP/VS Code extension concerns should also be verified in the complete diff (which was truncated), but the ExportLevel gap is clearly visible in the available code and must be fixed before merging. Once ExportLevel support is properly implemented throughout the pipeline (adding the field to AST node, processing it in the visitor, and setting it in the executor), this feature would be ready for approval. Automated review via OpenRouter (Nemotron Super 120B) — workflow source |
Closes #74
Summary
SHOW JSON STRUCTURES,DESCRIBE JSON STRUCTURE,CREATE [OR REPLACE] JSON STRUCTURE, andDROP JSON STRUCTUREarrays)
CUSTOM NAME MAPto override auto-generated ExposedNames (maps to Studio Pro's "Custom name" column)DESCRIBEoutputs re-executableCREATE OR REPLACEMDL with the element tree as commentsjson_structurescatalog table for SQL queryingNew MDL syntax